﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Runtime.InteropServices;

namespace UniversalPrinter
{
    internal class MSExcel : IDisposable
    {
        public void Dispose()
        {
            Close();
            Quit();

            oDocs = null;
            ExcelApplication = null;
            oBook = null;
            oDocs = null;
        }
        Type ExcelType;
        object ExcelApplication;
        object oBook;
        object oDocs;
        object[] oParams;
        object missing = System.Reflection.Missing.Value;

        public byte ExcelResult = 0;

        private string version = null;
        public string Version
        {
            get
            {
                if (version == null && ExcelType != null)
                {
                    version = ExcelApplication.GetType().InvokeMember("Version", System.Reflection.BindingFlags.GetProperty, null, ExcelApplication, null).ToString();
                }
                return version;
            }
        }

        public MSExcel()
        {
            try
            {
                ExcelType = Type.GetTypeFromProgID("Excel.Application");
                ExcelApplication = Activator.CreateInstance(ExcelType);
                ExcelResult = 0;
            }
            catch
            {
                ExcelResult = 3;
            }
        }

        public void Open(string strFileName)
        {
            if (ExcelType != null)
            {
                oDocs = ExcelApplication.GetType().InvokeMember("Workbooks", System.Reflection.BindingFlags.GetProperty, null, ExcelApplication, null, CultureInfo.InvariantCulture);
                oParams = new object[3];
                oParams[0] = strFileName;
                oParams[1] = missing;
                oParams[2] = true;

                oBook = oDocs.GetType().InvokeMember("Open", System.Reflection.BindingFlags.InvokeMethod, null, oDocs, oParams);
                ExcelResult = 0;
            }
        }

        public void Close()
        {
            if (ExcelType != null)
            {
                GC.Collect();
                GC.WaitForPendingFinalizers();
                Marshal.FinalReleaseComObject(oDocs);

                oBook.GetType().InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, oBook, null);

                Marshal.FinalReleaseComObject(oBook);
                ExcelResult = 0;
            }
        }

        public void Print(string printerName)
        {
            if (ExcelType != null)
            {
                oParams = new object[8];
                oParams[0] = missing;
                oParams[1] = missing;
                oParams[2] = missing;
                oParams[3] = missing;
                oParams[4] = printerName == null ? missing : printerName;
                oParams[5] = missing;
                oParams[6] = missing;
                oParams[7] = missing;

                oBook.GetType().InvokeMember("PrintOut", System.Reflection.BindingFlags.InvokeMethod, null, oBook, oParams);
                ExcelResult = 0;
            }
        }

        public void Quit()
        {
            if (ExcelType != null)
            {
                ExcelApplication.GetType().InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod, null, ExcelApplication, null);
                Marshal.FinalReleaseComObject(ExcelApplication);
            }
            oParams = null;
            missing = null;
            ExcelType = null;
            ExcelResult = 0;
        }
    }
}
